/**
 * 
 */
package com.newtribe.docsign.pdf;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.cert.CRL;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import net.sf.jsignpdf.Constants;

import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfDate;
import com.lowagie.text.pdf.PdfDictionary;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfPKCS7;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignature;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfString;

/**
 * @author newtribe
 *
 */
public class PdfSigner {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		 KeyStore ks = KeyStore.getInstance("pkcs12");
		 ks.load(new FileInputStream("D:/ca/cross-cert/usern/test.pfx"), "111111".toCharArray());
		 String alias = (String)ks.aliases().nextElement();
		 PrivateKey key = (PrivateKey)ks.getKey(alias, "111111".toCharArray());
		 Certificate[] chain = ks.getCertificateChain(alias);
		 PdfReader reader = new PdfReader("d:/iam.pdf");
		 FileOutputStream fout = new FileOutputStream("d:/signed23.pdf");
		 PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', null, true);
		 PdfSignatureAppearance sap = stp.getSignatureAppearance();
		 sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
		// sap.setReason("I'm the author");
		// sap.setLocation("Lisbon");
		 // comment next line to have an invisible signature
		
			sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
		 
			final String tmpImgPath = "E:/文档签名算法/yin22.jpg";
			if (tmpImgPath != null) {
				
				final Image img = Image.getInstance(tmpImgPath);
			 	sap.setSignatureGraphic(img);
				sap.setImage(img);
				
				//sap.setLayer2Text("layer2");
				
				//sap.setLayer4Text("lay4");
			}
			int lx =300,ly=600;
			sap.setContact("付伟");
			sap.setReason("完整性保护!");
			sap.setAcro6Layers(false);
			sap.setRender(PdfSignatureAppearance.SignatureRenderDescription);
			 sap.setVisibleSignature(new Rectangle(lx, ly, lx+100, ly+100), 1, null);
		
			 final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
				dic.setDate(new PdfDate(sap.getSignDate()));
				sap.setCryptoDictionary(dic);
				
				
				final int contentEstimated = (int) 25000 ;

				final Map<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
				exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
				sap.preClose(exc);


				byte[] paddedSig = new byte[contentEstimated];
				
				
				 final CertificateFactory cf = CertificateFactory.getInstance(Constants.CERT_TYPE_X509);
			       
				 InputStream inStream =new FileInputStream("e:/gfaapp1.crl");
				 final CRL crl = cf.generateCRL(inStream);
				 
				PdfPKCS7 sgn = new PdfPKCS7(key, chain, new CRL[]{crl}, "SHA-1", null, false);
				

				final MessageDigest messageDigest = MessageDigest.getInstance("sha-1");
				byte buf[] = new byte[8192];
				int n;
				InputStream data = sap.getRangeStream();
				while ((n = data.read(buf)) > 0) {
					messageDigest.update(buf, 0, n);
				}
				byte hash[] = messageDigest.digest();
				Calendar cal = Calendar.getInstance();

				byte sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, null);
				sgn.update(sh, 0, sh.length);
				byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, null, null);

				System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
				
				PdfDictionary dic2 = new PdfDictionary();
				dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
				sap.close(dic2);
			 
		 // stp.close();
		 System.out.println("===========over");


	}

}
